package wodegua.d29_多线程;

import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

/**
 * Lock锁
 * ●LocK锁是IDK5开始提供的一个新的锁定操作，通过它可以创建出锁对象进行加锁和解锁，更灵活、更方便、更强大。
 * ●Lock是接口，不能直接实例化，可以采用它的实现类ReentrantLock来构建Lock锁对象。
 *
 * 构造器
 * public ReentrantLock()       获得Lock锁的实现类对象
 *
 * Lock的常用方法
 * 方法名称
 * void lock()   获得锁
 * void unlock()    释放锁
 */
public class d5_thread_safe_lock {
    public static void main(String[] args) {
        AccountLock account = new AccountLock("id-1101",100000);
        new DrawThreadLock(account, "小明").start();
        new DrawThreadLock(account, "小红").start();

        AccountLock account2 = new AccountLock("id-1102",100000);
        new DrawThreadLock(account2, "小黑").start();
        new DrawThreadLock(account2, "小白").start();
    }
}


class AccountLock{
    private String cardId;
    private double money;
    private final Lock lk = new ReentrantLock();

    public AccountLock() {
    }

    public AccountLock(String cardId, double money) {
        this.cardId = cardId;
        this.money = money;
    }

    public void DrawMoney(double money){
        String name = Thread.currentThread().getName();
        try {
            lk.lock();
            if (this.money >= money) {
                System.out.println(name + "来取" + money);
                this.money -= money;
                System.out.println(name + "来取" + money + "后，余额="+this.money);
            } else {
                System.out.println(name + "来取钱余额不足");
            }
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            lk.unlock();
        }
    }

    public String getCardId() {
        return cardId;
    }

    public void setCardId(String cardId) {
        this.cardId = cardId;
    }

    public double getMoney() {
        return money;
    }

    public void setMoney(double money) {
        this.money = money;
    }
}

class DrawThreadLock extends Thread{
    private AccountLock account;
    public DrawThreadLock() {
    }

    public DrawThreadLock(AccountLock account, String name) {
        super(name);
        this.account = account;
    }

    @Override
    public void run() {
        account.DrawMoney(100000);
    }
}
